#include "ServeUtils.h"
#include "DefaultUtils.h"
extern int errno;

unsigned short portbase = 0;/**port base, for non-root servers*/

int passivesock(const char* service,const char* transport,int qlen)
{
    struct servent* pse;/**pointer to service information entry*/

    struct protoent* ppe;/**pointer to protocol information entry*/

    struct sockaddr_in sin;/**an Internet endpoint address*/
    int s,type;/**socket descriptor and socket type*/

    memset(&sin,0,sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = INADDR_ANY;

    /**Map service name to port number*/
    if((pse=getservbyname(service,transport)))
        sin.sin_port = htons(ntohs((unsigned short)pse->s_port)+portbase);
    else if((sin.sin_port = htons((unsigned short)atoi(service)))==0)
        errexit("can't get %s service entry \n",service);

    /**Map protocol name to protocol number*/
    if((ppe=getprotobyname(transport))==0)
        errexit("can't get %s protocol entry\n",transport);

    /**Use protocol to choose a socket type*/
    if(strcmp(transport,"udp")==0)
        type = SOCK_DGRAM;
    else
        type = SOCK_STREAM;

    /**Allocate a socket*/
    s = socket(PF_INET,type,ppe->p_proto);
    if(s<0)
        errexit("can't create socket: %s\n",strerror(errno));

    /**Bind the socket */
    if(bind(s,(struct sockaddr*)&sin,sizeof(sin))<0)
       errexit("can't bind to %s port: %s\n",service,strerror(errno));
    if(type == SOCK_STREAM && listen(s,qlen)<0)
       errexit("can't listen on %s port: %s\n",service,strerror(errno));

    printf("port:%d\n",sin.sin_port );
    return s;
    }


    int passiveUDP(const char* service,int qlen )
    {
        return passivesock(service,"udp",qlen);//max
    }

    int passiveTCP(const char* service,int qlen)
    {

        return passivesock(service,"tcp",qlen);//max
    }


int socketInit(const char* service,const char* transport,int qlen,unsigned int port)
{
      struct sockaddr_in s_addr;/**an Internet endpoint address*/
        int sockfd,type;/**socket descriptor and socket type*/

        if(strcmp(transport,"udp")==0)
            type = SOCK_DGRAM;
        else
            type = SOCK_STREAM;

             /*建立socket*/
        if((sockfd = socket(PF_INET, type, 0)) == -1)
            errexit("socket:%s\n",strerror(errno));
      //  else
       //     printf("socket create success!\n");
        memset(&s_addr,0,sizeof(s_addr));
        s_addr.sin_family = AF_INET;
        s_addr.sin_port = htons(port);
        s_addr.sin_addr.s_addr = htons(INADDR_ANY);

        /*把地址和端口帮定到套接字上*/
        if((bind(sockfd, (struct sockaddr*) &s_addr,sizeof(struct sockaddr))) == -1)
            errexit("bind:%s\n",strerror(errno));
       // else
         //   printf("bind port %d success!\n",port);
        /*侦听本地端口*/
        if(listen(sockfd,qlen) == -1)
            errexit("listen:%s\n",strerror(errno));
        //else
         //   printf("the server is listening!\n");
        return sockfd;

}


int socketInitTCP(const char* service,int qlen,unsigned int port)
{
    return socketInit(service,"tcp",qlen,port);
}

int socketInitUDP(const char* service,int qlen,unsigned int port)
{
    return socketInit(service,"udp",qlen,port);
}

int connectSocket(const char* ip,const char*  transport ,unsigned int port)
{
    int servesocket;
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);// htons((unsigned short)atoi(SERVE_PORT));
    sin.sin_addr.s_addr  = inet_addr(ip);//是否需要htons
    //创建套接字
    servesocket = socket(PF_INET,SOCK_STREAM,0);//这里不需要网络字节/？
  //  printf("here:\n%s,%d,%d\n",sin.sin_addr.s_addr,sin.sin_port,stats->servesocket.socketid);
    if( servesocket<0)
        {
        printf("connectSocket connect scoket failed.error id:%d\n",servesocket);
        return 0;
        }
        else
        printf("connectSocket create socket success.\n");
    //建立连接
    if(connect( servesocket,(struct sockaddr*)&sin,sizeof(sin))<0)
    {
        printf("connect failed\n");
        close(servesocket);
//        printf("ConsoleStatsDoOnline can't connect to %s.%d:%s \n",stats->servesocket.ip,stats->servesocket.port,strerror(errno));
        return 0;
    }
    else
        printf("connect success.\n");
        return servesocket;
}


